package com.ebupt.migu.music.approve.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.ebupt.migu.music.approve.entity.ReceiveMsgEvt;
import com.ebupt.migu.music.approve.entity.ReceiveMsgRt;
import com.ebupt.migu.music.approve.mapper.ApproveMapper;
import com.ebupt.migu.music.approve.mapper.SMSApproveRankInfoMapper;
import com.ebupt.migu.music.approve.service.ApproveService;
import com.ebupt.migu.music.common.auth.IDAuthUtils;
import com.ebupt.migu.music.common.constants.ApproveConstans;
import com.ebupt.migu.music.common.constants.StrategyConstants;
import com.ebupt.migu.music.common.entity.Page;
import com.ebupt.migu.music.common.entity.ResultObject;
import com.ebupt.migu.music.common.exception.MyException;
import com.ebupt.migu.music.common.exception.StatusEnum;
import com.ebupt.migu.music.common.sms.Sender;
import com.ebupt.migu.music.market.entity.MarketSmsAuditRecord;
import com.ebupt.migu.music.market.entity.ReceiveMsgResp;
import com.ebupt.migu.music.market.enums.ReturnCode;
import com.ebupt.migu.music.strategy.mapper.StrategyMapper;
import com.ebupt.migu.music.strategy.service.StrategyService;
import com.ebupt.migu.music.system.entity.SysUser;
import com.ebupt.migu.music.system.mapper.UserMapper;
import com.ebupt.migu.music.unifyAudit.service.UnifyAuditService;
import com.ebupt.migu.music.userGroup.mapper.CrowdMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * Created by Intellij IDEA. User: liuyangyang@cd.ebupt.com Date: 2019/10/9
 */
@Slf4j
@Service
public class ApproveServiceImpl implements ApproveService {

    @Autowired
    private ApproveMapper approveMapper;
    @Autowired
    private CrowdMapper crowdMapper;
    @Autowired
    private StrategyMapper strategyMapper;
    @Autowired
    private StrategyService strategyService;
    @Autowired
    private SMSApproveRankInfoMapper smsApproveRankInfoMapper;
    @Resource
    private UnifyAuditService unifyAuditService;
    @Autowired
    private IDAuthUtils idAuthUtils;

    @Autowired
    private UserMapper userMapper;


    /**
     * 分页、条件查询审批记录 查询条件：申请时间- createTime; 审批状态- approveStatus; 默认创建时间倒序排列 审批状态：1-待审批；2-已通过；3-已驳回；
     *
     * @param params
     * @return
     */
    @Override
    public ResultObject queryApproveList(Map<String, Object> params) {
        ResultObject res = new ResultObject();
        List<HashMap<String, Object>> datas = new ArrayList<>();
        Integer total;
        if ("1".equals(params.get("isAdmin")) || "1".equals(params.get("isAuditor"))) {
            // 超级管理员有权查询所有审批列表
            params.remove("creatorId");
            // 短信审核流程升级 -- 不再仅查询审核人本部门的活动，默认查询全站活动
            params.remove("creatorDepartment");
        }
        log.info("params:{}", params.toString());
        List<Byte> executeStatus = new ArrayList<>();
        // 对应审批状态
        if (params.get("approveStatus").toString().equals("1")) {
            executeStatus.add(StrategyConstants.EXECUTE_CHECKING);
        }
        if (params.get("approveStatus").toString().equals("2")) {
            executeStatus.add(StrategyConstants.EXECUTE_UNEXECUTED);
            executeStatus.add(StrategyConstants.EXECUTE_ONGOING);
            executeStatus.add(StrategyConstants.EXECUTE_TERMINATED);
            executeStatus.add(StrategyConstants.EXECUTE_ENDED);
        }
        if (params.get("approveStatus").toString().equals("3")) {
            executeStatus.add(StrategyConstants.EXECUTE_REJECTED);
        }
        params.put("executeStatus", executeStatus);

        try {
            // 当前条件总条数
            total = approveMapper.countApproveList(params);
            // 结果集
            datas = approveMapper.queryApproveList(params);

            for (HashMap<String, Object> data : datas) {
                // 判断统一审核是否走完
                if ("1".equals(String.valueOf(data.get("isUnifyAudit")))) {
                    Boolean next = unifyAuditService.isNext(String.valueOf(data.get("strategyId")));
                    data.put("next", next);
                }
                // 短信策略的审核人单独处理
                if (null != data.get("strategyType") && "1".equals(String.valueOf(data.get("strategyType")))) {
                    List<HashMap<String, Object>> ranks =
                            smsApproveRankInfoMapper.queryByActivityId(String.valueOf(data.get("strategyId")));
                    data.put("ranks", ranks);
                }
            }
        } catch (Exception e) {
            log.error("查询审批列表失败", e);
            throw new MyException(StatusEnum.ERROR, "查询审批列表失败");
        }
        // 分页
        Page<HashMap<String, Object>> page = new Page<>();
        page.setTotal(total);
        page.setData(datas);
        res.setMsg("查询审批列表成功");
        res.setData(page);
        return res;
    }

    /**
     * 提交审核 1、 验证当前提交审核的是否是超级管理员或者指定审批人 2、 修改审批状态、将审批记录同时填写到策略列表
     *
     * @param params
     * @return
     */


    @Override
    @Transactional(rollbackFor = MyException.class)
    public ResultObject submit(Map<String, Object> params) {
        strategyMapper.deleteNumber(params.get("strategyId").toString());
        // 验证是否是超管或者记录指定审批人
        if (!("1").equals(params.get("isAuditor")) && !("1").equals(params.get("isAdmin"))
                && !params.get("approverId").equals(params.get("creatorId"))) {
            throw new MyException(StatusEnum.OPERATE_LIMITED, "当前用户无审批权");
        }

        // 获取审批状态以策略类型
        byte status = Byte.valueOf(params.get("approveStatus").toString());
        byte strategyType = Byte.valueOf(params.get("strategyType").toString());
        String strategyId = String.valueOf(params.get("strategyId"));
        // strategy_info需要修改的信息
        Map<String, Object> strParams = new HashMap<>();
        strParams.put("approverId", params.get("approverId"));
        strParams.put("approverName", params.get("approverName"));
        strParams.put("strategyId", strategyId);

        String jobType = "";
        String sms_content = "";
        Map<String, Object> strategy_info = strategyMapper.queryByStrategyId(strategyId);
        if (strategyType == StrategyConstants.TYPE_SMS) {
            sms_content = strategy_info.get("smsContent").toString();
            // 任务类型：1-立即执行；2-单次执行；3-循环（重复）执行；4-间隔执行；
            String object = strategy_info.get("jobType").toString();
            if (object.equals("1")) {
                jobType = "立即执行";
            }

            if (object.equals("2")) {
                String start_time = strategy_info.get("startTime").toString();
                jobType = start_time;
            }

            if (object.equals("3")) {
                String start_time = strategy_info.get("startTime").toString();
                String end_time = strategy_info.get("endTime").toString();
                jobType = start_time + "至" + end_time;
            }

            if (object.equals("4")) {
                String start_time = strategy_info.get("startTime").toString();
                String end_time = strategy_info.get("endTime").toString();
                String interval_days = strategy_info.get("intervalDays").toString();
                jobType = start_time + "至" + end_time + "间隔:" + interval_days + "天";
            }

        }

        // 全网PUSH没有客群ID
        Integer broadcast_push = (null != strategy_info.get("broadcastPush"))
                ? Integer.valueOf(String.valueOf(strategy_info.get("broadcastPush"))) : 0;
        Integer createStatus = strategyMapper.queryGroupStatusByStrategyId(strategyId);
        if (broadcast_push == 0 && createStatus != 5) {
            throw new MyException(StatusEnum.USER_GROUP_UNFINISHED, "策略包含的客群未创建完成，暂不可审核下发策略");
        }

        // 批语
        if (null != params.get("approveDesc") && !"".equals(params.get("approveDesc"))) {
            strParams.put("remarks", params.get("approveDesc"));
        }

        boolean is2Megamarket = false;
        // 审核通过- 将相应策略状态修改为未开始
        if (status == ApproveConstans.APPROVE_PASS) {

            // 当前审核人成，修改审核状态
            Map<String, Object> current = params;
            current.put("approverId", params.get("approverId"));
            current.put("strategyId", params.get("strategyId"));
            current.put("approveStatus", 2);
            approveMapper.updateStatus(current);

            if (strategyType == StrategyConstants.TYPE_SMS) {
                // 查询顺序未审核的短信审核人
                HashMap<String, Object> rank = smsApproveRankInfoMapper.selectOneByActivityId(String.valueOf(params.get("strategyId")));

                // 将sms_approve_rank_info表中对应的审核人的审核状态更新为审核通过
                Map<String, Object> smsApproveRankInfoMap = new HashMap<>();
                smsApproveRankInfoMap.put("activityId", strategyId);
                smsApproveRankInfoMap.put("status", 2);
                smsApproveRankInfoMap.put("rank", params.get("rank"));
                smsApproveRankInfoMapper.updateSMSApproveRankInfoStatus(smsApproveRankInfoMap);


                HashMap group = crowdMapper.queryByGroupID(strategy_info.get("groupId").toString());
                if (null == rank) {
                    strParams.put("executeStatus", StrategyConstants.MEGAMARKET_APPROVE);
                    is2Megamarket = true;

                } else {
                    // 将sms_approve_rank_info表中的下一位审核人改成待审核
                    smsApproveRankInfoMap.clear();
                    smsApproveRankInfoMap.put("activityId", strategyId);
                    smsApproveRankInfoMap.put("rank", rank.get("rank"));
                    smsApproveRankInfoMap.put("status", 1);
                    smsApproveRankInfoMapper.updateSMSApproveRankInfoStatus(smsApproveRankInfoMap);

                    // 创建审核记录
                    Map<String, Object> next = new HashMap<>();
                    next.put("approverId", rank.get("approverId"));
                    next.put("approverName", rank.get("approverName"));
                    next.put("strategyId", rank.get("activityId"));
                    next.put("approveStatus", 1);
                    approveMapper.createApproveByMap(next);

                    // 将strategy_info表中的审核人指向下一位审核人
                    strParams.put("approverId", rank.get("approverId"));
                    strParams.put("approverName", rank.get("approverName"));
                    strParams.put("strategyId", params.get("strategyId"));
                    strategyMapper.updateApproveInfo(strParams);

                    // 返回本次审核结果
                    ResultObject res = new ResultObject();
                    res.setMsg("审批成功");
                    //通知审核
                    String mobile = strategyMapper.getMobile(rank.get("approverId").toString());
                    String randomId = getRandomId(strategyId, rank.get("approverId").toString());
                    Sender.sendSMS(
                            Sender.CHECK_CODE,
                            new String[]{mobile},
                            new String[]{
                                    strategy_info.get("strategyName").toString(),
                                    group.get("mobileUser").toString(),
                                    sms_content,
                                    jobType,
                                    randomId,
                                    randomId,
                            }
                    );
                    //短信告知审核通过
                    String mobile2 = strategyMapper.getMobile(params.get("approverId").toString());
                    Sender.sendSMS(
                            Sender.CHECK_LS_RESULT_CODE,
                            new String[]{mobile2},
                            new String[]{
                                    strategy_info.get("strategyName").toString(),
                            }
                    );
                    return res;
                }

            } else {

                strParams.put("executeStatus", StrategyConstants.EXECUTE_UNEXECUTED);
            }


        } else {
            // 当前审核人成，修改审核状态
            Map<String, Object> current = params;
            current.put("approverId", params.get("approverId"));
            current.put("strategyId", params.get("strategyId"));
            current.put("approveStatus", 3);
            approveMapper.updateStatus(current);

            if (strategyType == StrategyConstants.TYPE_SMS) {
                // 将sms_approve_rank_info表中对应的审核人的审核状态更新为审核驳回
                Map<String, Object> smsApproveRankInfoMap = new HashMap<>();
                smsApproveRankInfoMap.put("activityId", strategyId);
                smsApproveRankInfoMap.put("rank", params.get("rank"));
                smsApproveRankInfoMap.put("status", 3);
                smsApproveRankInfoMapper.updateSMSApproveRankInfoStatus(smsApproveRankInfoMap);

                String mobile = strategyMapper.getMobile(strategy_info.get("creatorId").toString());
                String mobile2 = strategyMapper.getMobile(params.get("approverId").toString());
                Sender.sendSMS(
                        Sender.CHECK_RESULT_CODE,
                        new String[]{mobile, mobile2},
                        new String[]{
                                strategy_info.get("strategyName").toString(),
                                "驳回"
                        }
                );
                strategyMapper.deleteNumber(strategyId);
            }
            // 审核不通过- 将相应策略状态修改为被驳回
            strParams.put("executeStatus", StrategyConstants.EXECUTE_REJECTED);
        }

        strategyMapper.updateApproveInfo(strParams);

        // 短信策略走大营销平台审批
        try {
            if (strategyType == StrategyConstants.TYPE_SMS) {
                if (is2Megamarket) {
                    Map<String, Object> strategyInfo = strategyMapper.queryByStrategyId(strategyId);
                    // 调用大营销平台审批接
                    strategyService.sendToMegamarketAudit(strategyInfo);
                    log.info("营销平台审批通过");
                    //短信通知
                    String mobile = strategyMapper.getMobile(strategy_info.get("creatorId").toString());
                    String mobile2 = strategyMapper.getMobile(params.get("approverId").toString());
                    Sender.sendSMS(
                            Sender.CHECK_RESULT_CODE,
                            new String[]{mobile, mobile2},
                            new String[]{
                                    strategy_info.get("strategyName").toString(),
                                    "通过"
                            }
                    );
                    strategyMapper.deleteNumber(strategyId);
                }

            }
        } catch (Exception e) {
            log.error("大营销平台审批失败", e);
            throw new MyException(StatusEnum.ERROR, "大营销平台审批失败");
        }
        ResultObject res = new ResultObject();
        res.setMsg("审批成功");
        return res;
    }

    @Override
    public ReceiveMsgRt receiveMsg(ReceiveMsgEvt receiveMsgEvt) {
        ReceiveMsgRt receiveMsgResp = new ReceiveMsgRt();

        try {
            Map<String, Object> params = new HashMap<>();
            log.info("短信审核通知回调参数：{}", receiveMsgEvt);
            String msgContent = receiveMsgEvt.getMsgContent();
            String type = msgContent.substring(0, 2);
            String smsNumber = msgContent.substring(2);
            if (smsNumber.length() == 4) {
                Map map = strategyMapper.selectNumber(smsNumber);
                String strategyId = map.get("strategyId").toString();
                String approvalId = map.get("approvalId").toString();
                String status = "";

                //回复DY审核通过，回复DN审核驳回。
                if (type.equals("DY") || type.equals("dy")) {
                    status = "2";
                }


                if (type.equals("DN") || type.equals("dn")) {
                    status = "3";
                }

                Map<String, Object> strategy = strategyMapper.queryByStrategyId(strategyId);
                String strategyType = strategy.get("strategyType").toString();
                List<HashMap<String, Object>> hashMaps = smsApproveRankInfoMapper.queryByActivityId(strategyId);
                HashMap<String, Object> rank = hashMaps.stream().filter(map1 -> map1.get("approverId").equals(approvalId)).findFirst().get();

                Map<String, Object> login = new HashMap<>(3);
                login.put("pageStart", 0);
                login.put("rows", 9999);
                login.put("loginName", approvalId);
                SysUser user = userMapper.queryByPage(login).get(0);
                params.put("cid", user.getId());
                params.put("creatorId", user.getLoginName());
                params.put("creatorName", user.getUserName());
                params.put("creatorDepartmentId", user.getDeptId());
                params.put("creatorDepartment", user.getDeptName());
                params.put("creatorPhone", user.getMobile());
                params.put("creatorEmail", user.getEmail());
                params = idAuthUtils.isAdmin(params);
                params.put("approveStatus", status);
                params.put("strategyType", strategyType);
                params.put("approverId", approvalId);
                params.put("strategyId", strategyId);
                params.put("rank", rank.get("rank"));
                this.submit(params);
            }
        } catch (Exception e) {
            receiveMsgResp.setReturnCode(ReturnCode.ReturnCode5.getCode());
            receiveMsgResp.setDescription(ReturnCode.ReturnCode5.getName());
            return receiveMsgResp;
        }
        receiveMsgResp.setReturnCode(ReturnCode.ReturnCode5.getCode());
        receiveMsgResp.setDescription(ReturnCode.ReturnCode5.getName());
        return receiveMsgResp;
    }

    /**
     * 通过策略ID查询审批记录
     *
     * @param params
     * @return
     */
    @Override
    public ResultObject queryApproveByStrategyId(Map<String, Object> params) {
        // strategyId为必传参数
        if (null == params.get("strategyId") || "".equals(params.get("strategyId"))) {
            throw new MyException(StatusEnum.BUSINID, "参数异常");
        }
        Map<String, Object> map = new HashMap<>();
        List<HashMap<String, Object>> datas;
        String strategyId = params.get("strategyId").toString();
        try {

            // approve history: 不包含短信未审核人 //历史审核人
            datas = approveMapper.queryApproveByStrategyId(strategyId);

            // 包含全量短信审核人
            List<HashMap<String, Object>> ranks =
                    smsApproveRankInfoMapper.selectAllByActivityId(String.valueOf(params.get("strategyId")));
            // 遍历，如果全量审核人中的某人不在history中，将此人审核状态标记为未审核
            if (null != ranks && ranks.size() != 0) {
                for (HashMap<String, Object> rank : ranks) {
                    HashMap<String, Object> temp = new HashMap<>();
                    temp.put("approverId", rank.get("approverId"));
                    temp.put("approverName", rank.get("approverName"));
                    temp.put("approveStatus", 4);
                    datas.add(temp);
                }
            }
            map.put("ourDetail", datas);
            map.put("unifyDetail", unifyAuditService.qryAudit(strategyId));
            return new ResultObject().success("查询策略审批记录成功", map);
        } catch (Exception e) {
            log.error("查询策略审批记录失败", e);
            throw new MyException(StatusEnum.ERROR, "查询策略审批记录失败");
        }
    }

    @Override
    public ResultObject queryApproveDetail(Map<String, Object> params) {
        ResultObject res = new ResultObject();
        res.setCode(StatusEnum.SUCCESS.getCode());
        res.setMsg(StatusEnum.SUCCESS.getMsg());
        res.setData(smsApproveRankInfoMapper.queryByActivityId(String.valueOf(params.get("strategyId"))));
        return res;
    }

    public String getRandomId(String strategyId, String approvalId) {
        Random random = new Random();
        String randomNumber;
        Map map;
        do {
            randomNumber = String.valueOf(random.nextInt(9000) + 1000);
            map = strategyMapper.selectNumber(randomNumber);
        } while (map != null);
        strategyMapper.insertNumber(randomNumber, strategyId, approvalId);
        return randomNumber;
    }
}
